/*
 * @(#)AbstractTemplateEngineEx.java 1.0 2020年06月04日
 *
 *  Copyright (c) 2016, YUNXI. All rights reserved.
 *  YUNXI PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.baomidou.mybatisplus.generator.engine;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.config.rules.FileTypeEx;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
 * <p>Title:AbstractTemplateEngineEx</p>
 * <p>Description: </p>
 *
 * @author 子曰
 * @date 2020/6/4 9:53
 * @since 0.1.0
 */
public abstract class AbstractTemplateEngineEx extends AbstractTemplateEngine{

    /**
     * 处理输出目录
     */
    @Override
    public AbstractTemplateEngineEx mkdirs() {
        getConfigBuilder().getPathInfo().forEach((key, value) -> {
            File dir = new File(value);
            if (!dir.exists()) {
                boolean result = dir.mkdirs();
                if (result) {
                    logger.debug("创建目录： [" + value + "]");
                }
            }
        });
        return this;
    }

    /**
     * 输出 java xml 文件
     */
    @Override
    public AbstractTemplateEngine batchOutput() {
        try {
            List<TableInfo> tableInfoList = getConfigBuilder().getTableInfoList();
            for (TableInfo tableInfo : tableInfoList) {
                Map<String, Object> objectMap = getObjectMap(tableInfo);
                Map<String, String> pathInfo = getConfigBuilder().getPathInfo();
                TemplateConfigEx template = (TemplateConfigEx) getConfigBuilder().getTemplate();
                // 自定义内容
                InjectionConfig injectionConfig = getConfigBuilder().getInjectionConfig();
                if (null != injectionConfig) {
                    injectionConfig.initMap();
                    objectMap.put("cfg", injectionConfig.getMap());
                    List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
                    if (CollectionUtils.isNotEmpty(focList)) {
                        for (FileOutConfig foc : focList) {
                            if (isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
                                writer(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
                            }
                        }
                    }
                }
                // Mprequestdto.java
                String requestDtoName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != requestDtoName && null != pathInfo.get(ConstValEx.REQUEST_DTO_PATH)) {
                    String dtoFile = String.format((pathInfo.get(ConstValEx.REQUEST_DTO_PATH) + File.separator + "%sReqDto.java"), requestDtoName);
                    if (isCreate(FileTypeEx.DTO, dtoFile)) {
                        writer(objectMap, templateFilePath(template.getRequestdto()), dtoFile);
                    }
                }
                // Mpreponsedto.java
                String responseDtoName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != responseDtoName && null != pathInfo.get(ConstValEx.RESPONSE_DTO_PATH)) {
                    String dtoFile = String.format((pathInfo.get(ConstValEx.RESPONSE_DTO_PATH) + File.separator + "%sRespDto.java"), responseDtoName);
                    if (isCreate(FileTypeEx.DTO, dtoFile)) {
                        writer(objectMap, templateFilePath(template.getResponsedto()), dtoFile);
                    }
                }
                // Mpiapi.java
                String iApiName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != iApiName && null != pathInfo.get(ConstValEx.IAPI_PATH)) {
                    String iApiFile = String.format((pathInfo.get(ConstValEx.IAPI_PATH) + File.separator + "I%sApi.java"), iApiName);
                    if (isCreate(FileTypeEx.IAPI, iApiFile)) {
                        writer(objectMap, templateFilePath(template.getIapi()), iApiFile);
                    }
                }
                // Mpiqueryapi.java
                String iQueryApiName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != iQueryApiName && null != pathInfo.get(ConstValEx.IQUERYAPI_PATH)) {
                    String iQueryApiFile = String.format((pathInfo.get(ConstValEx.IQUERYAPI_PATH) + File.separator + "I%sQueryApi.java"), iQueryApiName);
                    if (isCreate(FileTypeEx.IQUERYAPI, iQueryApiFile)) {
                        writer(objectMap, templateFilePath(template.getIqueryapi()), iQueryApiFile);
                    }
                }
                // Mpeo.java
                String eoName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != eoName && null != pathInfo.get(ConstValEx.EO_PATH)) {
                    String eoFile = String.format((pathInfo.get(ConstValEx.EO_PATH) + File.separator + "%sEo.java"), eoName);
                    if (isCreate(FileTypeEx.EO, eoFile)) {
                        writer(objectMap, templateFilePath(template.getEo()), eoFile);
                    }
                }
                // Mpmapper.java
                String mapperName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != mapperName && null != pathInfo.get(ConstValEx.MPR_PATH)) {
                    String mapperFile = String.format((pathInfo.get(ConstValEx.MPR_PATH) + File.separator + "%sMapper.java"), mapperName);
                    if (isCreate(FileTypeEx.MAPPER, mapperFile)) {
                        writer(objectMap, templateFilePath(template.getMpr()), mapperFile);
                    }
                }
                // Mpdas.java
                String dasName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != dasName && null != pathInfo.get(ConstValEx.DAS_PATH)) {
                    String dasFile = String.format((pathInfo.get(ConstValEx.DAS_PATH) + File.separator + "%sDas.java"), dasName);
                    if (isCreate(FileTypeEx.DAS, dasFile)) {
                        writer(objectMap, templateFilePath(template.getDas()), dasFile);
                    }
                }
                // Mpiservice.java
                String iserviceName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != iserviceName && null != pathInfo.get(ConstValEx.ISERVICE_PATH)) {
                    String iserviceFile = String.format((pathInfo.get(ConstValEx.ISERVICE_PATH) + File.separator + "I%sService.java"), iserviceName);
                    if (isCreate(FileTypeEx.ISERVICE, iserviceFile)) {
                        writer(objectMap, templateFilePath(template.getIservice()), iserviceFile);
                    }
                }
                // Mpservice.java
                String serviceName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != serviceName && null != pathInfo.get(ConstValEx.SVC_PATH)) {
                    String serviceFile = String.format((pathInfo.get(ConstValEx.SVC_PATH) + File.separator + "%sServiceImpl.java"), serviceName);
                    if (isCreate(FileTypeEx.SERVICE, serviceFile)) {
                        writer(objectMap, templateFilePath(template.getSvc()), serviceFile);
                    }
                }
                // Mpapi.java
                String apiName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != apiName && null != pathInfo.get(ConstValEx.API_PATH)) {
                    String apiFile = String.format((pathInfo.get(ConstValEx.API_PATH) + File.separator + "%sApiImpl.java"), apiName);
                    if (isCreate(FileTypeEx.API, apiFile)) {
                        writer(objectMap, templateFilePath(template.getApi()), apiFile);
                    }
                }
                // Mpqueryapi.java
                String queryApiName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != queryApiName && null != pathInfo.get(ConstValEx.QUERYAPI_PATH)) {
                    String queryApiFile = String.format((pathInfo.get(ConstValEx.QUERYAPI_PATH) + File.separator + "%sQueryApiImpl.java"), apiName);
                    if (isCreate(FileTypeEx.QUERYAPI, queryApiFile)) {
                        writer(objectMap, templateFilePath(template.getQueryapi()), queryApiFile);
                    }
                }
                // Mprest.java
                String restName = tableInfo.getEntityName().replaceFirst(ConstValEx.EO, StringUtils.EMPTY);
                if (null != restName && null != pathInfo.get(ConstValEx.REST_PATH)) {
                    String restFile = String.format((pathInfo.get(ConstValEx.REST_PATH) + File.separator + "%sRest.java"), restName);
                    if (isCreate(FileTypeEx.REST, restFile)) {
                        writer(objectMap, templateFilePath(template.getRest()), restFile);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("无法创建文件，请检查配置信息！", e);
        }
        return this;
    }

    /**
     * 检测文件是否存在
     *
     * @return 文件是否存在
     */
    protected boolean isCreate(FileTypeEx fileType, String filePath) {
        ConfigBuilder cb = getConfigBuilder();
        // 自定义判断
        InjectionConfig ic = cb.getInjectionConfig();
        if (null != ic && null != ic.getFileCreate()) {
            return false;//ic.getFileCreate().isCreate(cb, fileType, filePath);
        }
        // 全局判断【默认】
        File file = new File(filePath);
        boolean exist = file.exists();
        if (!exist) {
            file.getParentFile().mkdirs();
        }
        return !exist || getConfigBuilder().getGlobalConfig().isFileOverride();
    }


}
